#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
アイテム ビューレット機能

Mikan Python Web Framework
"""

__author__ = "K.Sonohara"
__status__ = "develop"
__version__ = "0.0.0_36"
__date__    = "2014/01/05"
__license__ = 'LGPL'

# ------------------------------------------------------------
## インポート
# ------------------------------------------------------------
# Python
import random

# ESiPC
from esipc import ESiPCProperty

# Mikan
from mikan.item import *
from mikan.item.attribute import sort_entities
from mikan.viewlet import *
from mikan.viewlet.formviewlet import AbstractMikanBaseFormViewlet

# ------------------------------------------------------------
## 変数
# ------------------------------------------------------------

# ------------------------------------------------------------
## 関数
# ------------------------------------------------------------

# ------------------------------------------------------------
## クラス
# ------------------------------------------------------------


# ------------------------------------------------------------
## Mikan メニューバー ビューレットクラス
#
class AbstractMikanItemViewlet(AbstractMikanBaseFormViewlet):

	def __init__(self, parent, action=None, name=None, method="post", target=None):
		super(AbstractMikanItemViewlet, self).__init__(parent, action, name, method, target)

		self.clazz = "item"
		self.FItem = None
		self.FItemForm = None
		self.FItemAction = None

	def set_item(self, value):
		self.FItem = value

	def get_item(self):
		return self.FItem

	def prepare(self):
		return self.item != None

	def is_readonly(self):
		return False

	def is_editing(self):
		return not self.isreadonly

	def set_item_action(self, action):
		self.item = action.item
		self.itemform = action.itemform
		self.FItemAction = action.item

	def get_item_action(self):
		return self.FItemAction

	def set_item_form(self, value):
		self.FItemForm = value

	def get_item_form(self):
		return self.FItemForm

	def get_field_lebel_class(self, parent, readonly, field):
		return "item_label"

	def add_field_lebel(self, parent, readonly, field):
		if field.isvisibled:
			th = MikanThViewlet(parent, nodevalue=field.itemcaption)
			th.clazz = self.get_field_lebel_class(parent, readonly, field)

	def get_icon_link(self):
		return u"info?id=%s"

	def is_query(self):
		return False

	def add_field_input_value(self, parent, readonly, icon, field, item):
		name = u"%s_%s" % ("item", field.itemname)
		value = item[field.itemname]

		# 日付
		if field.isdate:
			v = value
			try:
				v = v.strftime("%Y/%m/%d")
			except:
				pass

			input = MikanTextInputViewlet(parent, name, v, 32, None)
			input.id = name

			js =	MikanJSViewlet(parent)
			js.nodevalue = u"""
jQuery( function() {
	jQuery( '#%s' ).datepicker();
} );""" % (name)

			return input

		# 日付時間
		if field.isdatetime:
			v = value

			input = MikanTextInputViewlet(parent, name, v, 32, None)
			input.id = name

			js =	MikanJSViewlet(parent)
			js.nodevalue = u"""
jQuery( function() {
	jQuery( '#%s' ).datetimepicker();
} );""" % (name)

			return input

		# リスト
		if field.attribute.list != None:
			select = MikanSelectViewlet(parent, name, nodevalue=1)
			if (self.isquery) or (not field.isrequired):
				MikanOptionViewlet(select, value="", nodevalue="")
			if field.attribute.list.isentitylist:
				field.attribute.list.build_list(self.request.db)
			if field.attribute.list:
				if field.attribute.list.list:
					sorted = field.attribute.list.list.values()
					sorted = sort_entities(field.attribute.list, sorted)

					for list in sorted:
						selected = None
						key = None
						if list.key == value:
							selected = True
						MikanOptionViewlet(select, value=list.key, nodevalue=list.to_display_value(), selected=selected)

			return select

		# テキストエリア
		if field.ismultiline:
			return MikanTextareaViewlet(parent, name, field.width, field.height, nodevalue=value)

		# password
		if field.ispassword:
			return MikanPasswordInputViewlet(parent, name, field.width, field.attribute.length, nodevalue="")

		return MikanTextInputViewlet(parent, name, value, field.width, field.attribute.length)

	def add_field_value(self, parent, readonly, icon, field, item, even):
		# 値
		nvalue = item[field.itemname]

		if field.attribute.list == None:
			if field.ispassword:
				value = ""
			else:
				value = nvalue
		else:
			if field.attribute.list.isentitylist:
				field.attribute.list.build_list(self.request.db)
			value = field.attribute.to_display_value(nvalue)

		# 読み取り専用
		if field.isvisibled:
			c = "item_cell"
			if even:
				c = "item_cell2"

			# td
			td = MikanTdViewlet(parent)
			td.clazz = c

			if (not field.isenabled) or (readonly):
				# アイコン(ID)属性
				if icon:
					id = unicode(item.getIDValue())
					a = MikanAViewlet(td, href=self.iconlink % (id), nodevalue=unicode(value))

					img = MikanImgViewlet(a, alt=unicode(value), src=self.get_icon_url(item), clazz="icon_small")
				# 日付
				elif field.isdate:
					if (value == None):
						value = " "
					try:
#						if isinstance(value, datetime.datetime):
						value = value.strftime("%Y/%m/%d")
					except:
						pass
					td.nodevalue = value

				# 日付時間
				elif field.isdatetime:
					if (value == None):
						value = " "
					try:
#					if isinstance(value, datetime.datetime):
						value = value.strftime("%Y/%m/%d %H:%M")
					except:
						pass
					td.nodevalue = value
				# password
				elif field.ispassword:
					td.nodevalue = "**********************"
				# メール属性
				elif (value != None) and (isinstance(field.attribute, AbstractMailAttribute)):
					a = MikanAViewlet(td, href=u"mailto:%s" % (value), nodevalue=unicode(value))
				# URL属性
				elif (value != None) and (isinstance(field.attribute, AbstractURLAttribute)):
					a = MikanAViewlet(td, href=u"%s" % (value), nodevalue=unicode(value))
				# 複数行属性
				elif (value != None) and (field.ismultiline):
					pre = MikanPreViewlet(td, nodevalue=unicode(value))
				# その他
				else:
					if (value == None):
						value = " "
					td.nodevalue = unicode(value)

				return True
			else:
				td.clazz = c
				self.add_field_input_value(td, readonly, icon, field, item)

		return False

	def get_icon_url(self, item=None):
		i = item
		if i == None:
			i = self.itemform
		return u"%sitem/%s.png" % (self.request.imageurl, i.iconname)

	def get_title(self):
		fields = self.itemform.sorted_fields()

		try:
			title = None
			for field in fields:
				if field.isvisibled:
					break
			title = self.item[field.itemname]
			if title != None:
				return u" %s [%s]" % (self.itemform.itemcaption, title)
		except:
			pass
		return u" %s" % (self.itemform.itemcaption)

	def add_icon_title(self):
		# タイトル
		value = self.title
		title = MikanH1Viewlet(self, value)
		title.clazz = "content_title"

		# アイコン
		img = MikanImgViewlet(title, alt=value, src=self.get_icon_url(), clazz="icon")

		return title

	def add_content(self, fields, table):
		# フォーム本体
		tbody = MikanTbodyViewlet(table)
		even = False
		for field in fields:
			tr = MikanTrViewlet(tbody)
			tr.clazz = "item_row"
			self.add_field_lebel(tr, self.isreadonly or (not self.isediting), field)
			self.add_field_value(tr, self.isreadonly or (not self.isediting), False, field, self.item, even)
			even = not even
		return tbody

	def get_item_action_number(self):
		return self.request.get_param_str("item_action", None)

	# ----------------------------------------------------
	## 処理
	# @return Trueなら続行
	def build_content(self):
		fields = self.itemform.sorted_fields()

		# タイトル
		self.add_icon_title()

		# エラー表示
		MikanExceptionsViewlet(self)

		# フォーム
		form = self
		f = self.formaction
		if self.islogdebug:
			self.logger.debug(f)
		if f != None:
			form = MikanFormViewlet(self, action=f, name="item")
			MikanHiddenInputViewlet(form, "item_action", str(random.uniform(1, 10000000)))
			if not self.isquery:
				try:
					MikanHiddenInputViewlet(form, "id", unicode(self.item.getIDValue()))
				except:
					pass

		# ボタン
		self.add_buttons(form)

		# テーブル
		table = MikanTableViewlet(form)
		table.clazz = "item_list"
		table.id = "item_list"

		# フォーム本体
		self.add_content(fields, table)

		# ボタン
		self.add_buttons(form)

	# ----------------------------------------------------
	## Property
	iconlink = ESiPCProperty(get_icon_link, None, None)
	item = ESiPCProperty(get_item, set_item, None)
	isediting = ESiPCProperty(is_editing, None, None)
	isreadonly = ESiPCProperty(is_readonly, None, None)
	isquery = ESiPCProperty(is_query, None, None)
	itemform = ESiPCProperty(get_item_form, set_item_form, None)
	itemaction = ESiPCProperty(get_item_action, set_item_action, None)
	itemactionnumber = ESiPCProperty(get_item_action_number, None, None)


# ------------------------------------------------------------
## Mikan メニューバー ビューレットクラス
#
class MikanItemResultViewlet(AbstractMikanItemViewlet):

	def is_create_button(self):
		return self.FIsCreateButton

	def set_item_action(self, action):
		super(MikanItemResultViewlet, self).set_item_action(action)
		self.items = action.items

	def add_buttons(self, parent):
		buttons = super(MikanItemResultViewlet, self).add_buttons(parent)

		if self.iscreatebutton:
			self.add_button(buttons, u"作成", "create")

		try:
			self.add_button(buttons, u"エクスポート", None, "$('#dialog_exports').dialog('open');")
		except:
			pass

		if self.request.ispostmethod:
			self.add_button(buttons, u"再検索", "query?re=%s" % self.itemactionnumber)

		self.add_button(buttons, u"検索", "query")

		return buttons

	def get_form_action(self):
		return None

	def __init__(self, parent, create=True):
		super(MikanItemResultViewlet, self).__init__(parent)

		self.FItems = None
		self.FIsCreateButton = create

	def get_field_lebel_class(self, parent, readonly, field):
		return "item_header"

	def add_field_lebel(self, parent, readonly, field):
		if (field.isresulttype):
			super(MikanItemResultViewlet, self).add_field_lebel(parent, readonly, field)

	def is_readonly(self):
		return True

	def set_items(self, value):
		self.FItems = value

	def get_items(self):
		return self.FItems

	def prepare(self):
		return self.items != None

	def get_title(self):
		return u" %s" % (self.itemform.itemcaption)

	def add_content(self, fields, table):
		# フォームヘッダー
		thead = MikanTheadViewlet(table)
		trHeader = MikanTrViewlet(thead)
		for field in fields:
			self.add_field_lebel(trHeader, self.isreadonly, field)

		# フォーム本体
		tbody = MikanTbodyViewlet(table)
		for item in self.items:
			tr = MikanTrViewlet(tbody)
			tr.clazz = "item_row"

			icon = True
			for field in fields:
				result = self.add_field_value(tr, self.isreadonly, icon, field, item, False)
				if result:
					icon = False

		return tbody

	def add_field_value(self, parent, readonly, icon, field, item, even):
		if field.isvisibled:
			if (field.isresulttype):
				return super(MikanItemResultViewlet, self).add_field_value(parent, readonly, icon, field, item, even)
		return False

	def add_sort_javascript(self, parent):
		js =	MikanJSViewlet(parent)
		js.nodevalue = u"""
var sorter = new TINY.table.sorter('sorter');
sorter.head = 'item_header';
sorter.asc = 'item_asc';
sorter.desc = 'item_desc';
sorter.even = 'item_cell';
sorter.odd = 'item_cell2';
sorter.evensel = 'item_cell_selected';
sorter.oddsel = 'item_cell2_selected';
sorter.paginate = false;
sorter.init('item_list',0);
"""
		return js

	def add_export_dialog(self):
		div = MikanDivViewlet(self)
		div.title = u"エクスポート"
		div.id = "dialog_exports"
		div.clazz = "dialog"

		form = MikanFormViewlet(div, action="exports", enctype=None)
		form.name = "exports"
		form.method = "post"

		select = MikanSelectViewlet(form, "filetype")
		select.size = 1
		self.add_exports(select)

		MikanBrViewlet(form)
		check = MikanCheckboxInputViewlet(form, "key", u"True")
		check_text = MikanTextViewlet(check, u"内部キーで出力")

		MikanBrViewlet(form)
		all = MikanCheckboxInputViewlet(form, "all", u"True")
		all_text = MikanTextViewlet(all, u"全ての属性を出力")

		num = self.itemactionnumber
		if num == None:
			num = "-1"
		MikanHiddenInputViewlet(form, "re", num)
		MikanHiddenInputViewlet(form, "item_action", num)

		MikanHrViewlet(form)

		buttons = super(MikanItemResultViewlet, self).add_buttons(div)
		self.add_button(buttons, u"エクスポート", None, "document.exports.submit();")

	def add_exports(self, select):
		MikanOptionViewlet(select, value="json", nodevalue=u"JSONファイル")
		MikanOptionViewlet(select, value="csv", nodevalue=u"CSVファイル")
		MikanOptionViewlet(select, value="xml", nodevalue=u"XMLファイル")
#		MikanOptionViewlet(select, value="pdf", nodevalue=u"PDF")
#		MikanOptionViewlet(select, value="excel", nodevalue=u"Excel")

	# ----------------------------------------------------
	## 処理
	# @return Trueなら続行
	def perform(self):
		# エクスポートダイアログ
		self.add_export_dialog()

		# 継承元実行
		if not super(MikanItemResultViewlet, self).perform():
			return False

		# 実行結果
		return True

	# ----------------------------------------------------
	## Property
	items = ESiPCProperty(get_items, set_items, None)
	isreadonly = ESiPCProperty(is_readonly, None, None)
	iscreatebutton = ESiPCProperty(is_create_button, None, None)

# ------------------------------------------------------------
## Mikan メニューバー ビューレットクラス
#
class AbstractMikanItemSingleViewlet(AbstractMikanItemViewlet):

	def __init__(self, parent):
		super(AbstractMikanItemSingleViewlet, self).__init__(parent)

	def add_buttons(self, parent):
		buttons = super(AbstractMikanItemSingleViewlet, self).add_buttons(parent)

		if not self.isreadonly:
			self.add_button(buttons, u"実行", None, "item_submit();")
		if self.isediting:
			self.add_button(buttons, u"初期状態", None, "item_reset();")
			self.add_button(buttons, u"全てクリア", None, "item_clear();")

		self.add_button(buttons, u"戻る", None, "history.back()")


		return buttons

# ------------------------------------------------------------
## Mikan メニューバー ビューレットクラス
#
class MikanItemQueryViewlet(AbstractMikanItemSingleViewlet):

	def is_query(self):
		return True

	def __init__(self, parent):
		super(MikanItemQueryViewlet, self).__init__(parent)

	def get_title(self):
		return u" %s" % (self.itemform.itemcaption)

	# ----------------------------------------------------
	## Property
	isquery = ESiPCProperty(is_query, None, None)


# ------------------------------------------------------------
## Mikan メニューバー ビューレットクラス
#
class MikanItemInfoViewlet(AbstractMikanItemSingleViewlet):

	def is_edit(self):
		return self.FIsEdit

	def get_mail_link(self):
		return u"mail?id=%s"

	def get_remove_link(self):
		return u"remove?id=%s"

	def get_update_link(self):
		return u"update?id=%s"

	def get_copy_link(self):
		return u"copy?id=%s"

	def add_buttons(self, parent):
		buttons = super(AbstractMikanItemSingleViewlet, self).add_buttons(parent)

		id = unicode(self.item.getIDValue())

		if self.maillink != None:
			self.add_button(buttons, u"メール送信", self.maillink % (id), None)

		try:
			self.add_button(buttons, u"エクスポート", None, "$('#dialog_export').dialog('open');")
		except:
			pass


		if self.isedit:
			if self.updatelink != None:
				self.add_button(buttons, u"編集", self.updatelink % (id), None)
			if self.copylink != None:
				self.add_button(buttons, u"コピー", self.copylink % (id), None)
			if self.removelink != None:
				self.add_button(buttons, u"削除", self.removelink % (id), None)
		self.add_button(buttons, u"戻る", None, "history.back()")

		return buttons

	def get_form_action(self):
		return None

	def __init__(self, parent, isedit=True):
		super(MikanItemInfoViewlet, self).__init__(parent)

		self.FIsEdit = isedit

	def is_readonly(self):
		return True

	# ----------------------------------------------------
	## 処理
	# @return Trueなら続行
	def perform(self):
		# エクスポートダイアログ
		self.add_export_dialog()

		# 継承元実行
		if not super(MikanItemInfoViewlet, self).perform():
			return False

		# 実行結果
		return True

	def add_export_dialog(self):
		div = MikanDivViewlet(self)
		div.title = u"エクスポート"
		div.id = "dialog_export"
		div.clazz = "dialog"

		form = MikanFormViewlet(div, action="export", enctype=None)
		form.name = "export"
		form.method = "get"

		select = MikanSelectViewlet(form, "filetype")
		select.size = 1
		self.add_exports(select)

		MikanBrViewlet(form)
		check = MikanCheckboxInputViewlet(form, "key", u"True")
		check_text = MikanTextViewlet(check, u"内部キーで出力")

		MikanBrViewlet(form)
		all = MikanCheckboxInputViewlet(form, "all", u"True")
		all_text = MikanTextViewlet(all, u"全ての属性を出力")

		MikanHiddenInputViewlet(form, "id", self.item.getIDValue())
		MikanHiddenInputViewlet(form, "item_action", True)

		MikanHrViewlet(form)

		buttons = super(AbstractMikanItemSingleViewlet, self).add_buttons(div)
		self.add_button(buttons, u"エクスポート", None, "document.export.submit();")

	def add_exports(self, select):
		MikanOptionViewlet(select, value="text", nodevalue=u"テキストファイル")
		MikanOptionViewlet(select, value="json", nodevalue=u"JSONファイル")
		MikanOptionViewlet(select, value="csv", nodevalue=u"CSVファイル")
		MikanOptionViewlet(select, value="xml", nodevalue=u"XMLファイル")
#		MikanOptionViewlet(select, value="pdf", nodevalue=u"PDF")
#		MikanOptionViewlet(select, value="excel", nodevalue=u"Excel")

	# ----------------------------------------------------
	## Property
	isedit = ESiPCProperty(is_edit, None, None)
	maillink = ESiPCProperty(get_mail_link, None, None)
	removelink = ESiPCProperty(get_remove_link, None, None)
	updatelink = ESiPCProperty(get_update_link, None, None)
	copylink = ESiPCProperty(get_copy_link, None, None)

# ------------------------------------------------------------
## Mikan メニューバー ビューレットクラス
#
class MikanItemCreateViewlet(AbstractMikanItemSingleViewlet):

	def __init__(self, parent):
		super(MikanItemCreateViewlet, self).__init__(parent)

	def get_title(self):
		return u" %s" % (self.itemform.itemcaption)

# ------------------------------------------------------------
## Mikan メニューバー ビューレットクラス
#
class MikanItemMailViewlet(AbstractMikanItemSingleViewlet):

	def get_title(self):
		return u"メール送信 - %s" % (super(MikanItemMailViewlet, self).get_title())

	def is_editing(self):
		return True

	def __init__(self, parent):
		super(MikanItemMailViewlet, self).__init__(parent)

	def add_content(self, fields, table):
		# フォーム本体
#		tbody =super(MikanItemMailViewlet, self).add_content(fields, table)
		tbody = MikanTbodyViewlet(table)

		field = fields[0]
		tr = MikanTrViewlet(tbody)
		tr.clazz = "item_row"
		self.add_field_lebel(tr, True, field)
		self.add_field_value(tr, True, False, field, self.item, False)

		tr = MikanTrViewlet(tbody)
		tr.clazz = "item_row"
		th = MikanThViewlet(tbody, nodevalue=u"メール送信先")
		th.clazz = "item_label"
		td = MikanTdViewlet(tbody)
		td.clazz = "item_cell2"
		MikanTextInputViewlet(td, "mailto", "", 64, 128)

# ------------------------------------------------------------
## Mikan メニューバー ビューレットクラス
#
class MikanItemRemoveViewlet(AbstractMikanItemSingleViewlet):

	def is_editing(self):
		return False

	def __init__(self, parent):
		super(MikanItemRemoveViewlet, self).__init__(parent)

# ------------------------------------------------------------
## Mikan メニューバー ビューレットクラス
#
class MikanItemUpdateViewlet(AbstractMikanItemSingleViewlet):

	def __init__(self, parent):
		super(MikanItemUpdateViewlet, self).__init__(parent)

# ------------------------------------------------------------
## Mikan メニューバー ビューレットクラス
#
class MikanItemSequenceUpViewlet(AbstractMikanItemSingleViewlet):

	def __init__(self, parent):
		super(MikanItemSequenceUpViewlet, self).__init__(parent)

# ------------------------------------------------------------
## Mikan メニューバー ビューレットクラス
#
class MikanItemSequenceRemoveViewlet(AbstractMikanItemSingleViewlet):

	def __init__(self, parent):
		super(MikanItemSequenceRemoveViewlet, self).__init__(parent)

# ------------------------------------------------------------
## Mikan メニューバー ビューレットクラス
#
class MikanItemCopyViewlet(AbstractMikanItemSingleViewlet):

	def __init__(self, parent):
		super(MikanItemCopyViewlet, self).__init__(parent)

# ------------------------------------------------------------
## メイン関数
# ------------------------------------------------------------
## メイン処理
if __name__ == '__main__':
	pass

# ------------------------------------------------------------
